/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package analiseSintatica.Regras.Expressoes;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Regra;
import analiseSintatica.estruturadados.NoArvore;
import java.util.LinkedList;

/**
 *
 * @author linton
 */
public class RegraVariavel extends Regra {

    protected static Regra instancia;

    RegraElementoVar regra_elementoVar = RegraElementoVar.getInstance();
    protected String estrutura = "<elemento_var> | '*' identificador";



    /**
     * Construtor privado necessario ao singleton
     */
    private RegraVariavel() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraVariavel getInstance() {
        if (instancia == null) {
            instancia = new RegraVariavel();
        }
        return (RegraVariavel) instancia;
    }

    @Override
    public NoArvore analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {

        NoArvore noVariavel = new NoArvore("<variavel>", false);

        if (listaTokens.getFirst().getToken().contains("operador_multiplicacao")){
            noVariavel.adicionaFilho(reconhecerAsterisco(listaTokens));
            noVariavel.adicionaFilho(reconhecerIdentificador(listaTokens));
        }
        else
            noVariavel.adicionaFilho(reconhecerElemento_Var(listaTokens));

        return noVariavel;
    }

    public NoArvore reconhecerElemento_Var (LinkedList<LinkToken> listaTokens) throws ErroSintaticoException{

        LinkToken token = listaTokens.getFirst();

        if(regra_elementoVar.getPrimeiro().contains(token.getToken())){
            return regra_elementoVar.analisar(listaTokens);
        }
        ErroSintaticoException erro = new ErroSintaticoException();
        erro.addErros("Falta Elemento_Var", estrutura, token.getLinha());
        throw erro;
    }

    public NoArvore reconhecerAsterisco (LinkedList<LinkToken> listaTokens) throws ErroSintaticoException{
        LinkToken token = listaTokens.removeFirst();
        if(token.getToken().equals("operador_multiplicacao")){
            return new NoArvore("operador_multiplicacao", true);
        }
        ErroSintaticoException erro = new ErroSintaticoException();
        erro.addErros("Falta operador multiplicacao*", estrutura, token.getLinha());
        throw erro;
    }

    public NoArvore reconhecerIdentificador(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {
        LinkToken token = listaTokens.removeFirst();

        if (token.getToken().equals("identificador")) {
            return new NoArvore("identificador", true);
        }
        ErroSintaticoException erro = new ErroSintaticoException();
        erro.addErros("Falta identificador", estrutura, token.getLinha());
        throw erro;
    }

    

    @Override
    protected void setPrimeiro() {
       // getUniao(primeiro, RegraElementoVar.getInstance().getPrimeiro());
        //primeiro.add("*");
        //  P(variavel) = { '*' } U { 'identificador' }
        this.primeiro.add("*");
        this.primeiro.add("identificador");
    }

    @Override
    protected void setSeguinte() {
        this.seguinte.add("=");
    }
}
